package com.gitee.huanminabc.jcommon.reflect;

import lombok.extern.slf4j.Slf4j;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 简要描述
 *
 * @Author: huanmin
 * @Date: 2025/4/3 01:24
 * @Version: 1.0
 * @Description: 文件作用详细描述....
 */
@Slf4j
public class GenericUtil {

    //获取指定接口的第index位置的泛型
    public static Class<?> getClassInterfaceGeneric(Class<?> zClass, Class<?> interfaceClass, int index) {
        Type[] genericInterfaces = zClass.getGenericInterfaces();
        for (Type genericInterface : genericInterfaces) {
            Class<?> rawType = ((ParameterizedTypeImpl) genericInterface).getRawType();
            if (rawType.equals(interfaceClass)) {
                Type[] params = ((ParameterizedType) genericInterface).getActualTypeArguments();
                if (index >= params.length || index < 0) {
                    return null;
                }
                return (Class<?>) params[index];
            }
        }
        //如果没有找到泛型接口，返回null
        return null;
    }


    /**
     * <p>
     * 反射对象获取泛型
     * </p>
     *
     * @param clazz new ArrayList<UserEntity>(){}; 匿名内部类写法才能获取到泛型
     * @param index 泛型所在位置
     * @return Class
     */
    public static Class<?> getClassGenericType(final Class<?> clazz, int index) {
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType)) {
            return null;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0) {
            return null;
        }
        return (Class<?>) params[index];
    }


    //Field 类的泛型比如List<String> list;
    public static Class<?> getFieldGenericType(final Field field, int index) {
        Type genType = field.getGenericType();
        if (!(genType instanceof ParameterizedType)) {
            return null;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (params.length == 0) {
            return null;
        }
        if (index >= params.length || index < 0) {
            return null;
        }
        return (Class<?>) params[index];
    }

    //Parameter 类的泛型比如List<String> list;
    public static Class<?> getParameterGenericType(final Parameter parameter, int index) {
        Type genType = parameter.getParameterizedType();
        if (!(genType instanceof ParameterizedType)) {
            return null;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (params.length == 0) {
            return null;
        }
        if (index >= params.length || index < 0) {
            return null;
        }
        return (Class<?>) params[index];
    }

}
